package com.blacamdk.ChatNetModule;

import com.blacamdk.ChatDatabase.ChatDatabaseInterface;
import com.blacamdk.ChatSecret.MD5Util;
import com.mysql.jdbc.Util;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.sql.PseudoColumnUsage;
import java.sql.ResultSet;
import java.util.Arrays;

/**
 * UDPServer
 *
 * @author BlacAmDK
 * @date 16-12-20
 */
public class UDPServer {
    private static DatagramSocket datagramSocket = null; // 连接对象
    public UDPServer() {
        try {
            init();
            while(true){
                try {
                    byte[] buffer = new byte[1024 * 64]; // 缓冲区
                    DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
                    receive(packet);
                    new Thread(new ServiceImpl(packet)).start();
                } catch (Exception ignored) {
                }
                Thread.sleep(1000);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 接收数据包，该方法会造成线程阻塞
     */
    private static DatagramPacket receive(DatagramPacket packet) throws Exception {
        datagramSocket.receive(packet);
        return packet;
    }
    /**
     * 将响应包发送给请求端
     */
    static void response(DatagramPacket packet) {
        try {
            datagramSocket.send(packet);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 初始化连接
     */
    private static void init(){
        try {
            InetSocketAddress socketAddress = new InetSocketAddress(ServerMain.port);
            datagramSocket = new DatagramSocket(socketAddress);
            datagramSocket.setSoTimeout(5 * 1000);
            System.out.println("服务端启动成功");
        } catch (Exception e) {
            datagramSocket = null;
            System.err.println("服务端启动失败");
            e.printStackTrace();
        }
    }
}
class ServiceImpl implements Runnable {
    private DatagramPacket packet;
    ServiceImpl(DatagramPacket packet){
        this.packet = packet;
    }
    public void run() {
        try {
            byte[] bt = new byte[packet.getLength()];
            System.arraycopy(packet.getData(), 0, bt, 0, packet.getLength());

            String[] psend = Utils.Analyze(new String(bt));
            if(psend != null)
            {
                switch (Integer.parseInt(psend[0]))
                {
                    case 20://登录
                        ChatDatabaseInterface.ERR_TYPE ret;
                        ret = ServerMain.database.login(psend[1], psend[2], Integer.parseInt(psend[4]), psend[3]);
                        if(ret == ChatDatabaseInterface.ERR_TYPE.OK) {
                            bt = ("21 " + ret + ' ' + ServerMain.database.getUID(psend[1])).getBytes("UTF-8");
                        }else
                        {
                            bt = ("21 " + ret).getBytes("UTF-8");
                        }
                        break;
                    case 15://注册
                        ChatDatabaseInterface.ERR_TYPE ret2;
                        ret2 = ServerMain.database.register(psend[1], psend[2]);
                        bt = ("16 " + ret2).getBytes("UTF-8");
                        break;
                    case 30://发送消息
                        long ret3 = ServerMain.database.send_to(psend[1], Integer.parseInt(psend[2]), Integer.parseInt(psend[3]), psend[4]);
                        bt = ("31 " + ret3).getBytes("UTF-8");
                        break;
                    case 10://拉取用户列表//有问题待修复
                        ResultSet rs = ServerMain.database.getUserList(psend[1], Integer.parseInt(psend[2]));
                        if(rs == null) { bt = "11 0".getBytes("UTF-8"); break; }//没有人在线（不可能出现，所以一定是出了错）
                        byte[] bytetmp = new byte[61000];
                        int used;
                        int tmp = 0;
                        tmp = Utils.addbyte(bytetmp, "11 ".getBytes("UTF-8"), tmp);
                        do{
                            used = tmp;
                            tmp = Utils.addbyte(bytetmp, (rs.getInt("UID") + " " + rs.getString("Username") + " ").getBytes("UTF-8"), used);
                        }while (rs.next() && tmp != used);
                        used = Utils.addbyte(bytetmp, ("" + (tmp != used ? 0 : -1)).getBytes("UTF-8"), tmp);
                        bt = new byte[used];
                        System.arraycopy(bytetmp, 0, bt, 0, used);
                        break;
                    case 40://获取消息
                        ResultSet rs2 = ServerMain.database.receive(psend[1], Integer.parseInt(psend[2]), Long.parseLong(psend[3]));
                        if(rs2 == null) { bt = "41 0".getBytes("UTF-8"); break; }//没有消息
                        byte[] bytetmp2 = new byte[61000];
                        int used2;
                        int tmp2 = 0;
                        tmp2 = Utils.addbyte(bytetmp2, "41 ".getBytes("UTF-8"), tmp2);
                        do{
                            used2 = tmp2;
                            tmp2 = Utils.addbyte(bytetmp2, (rs2.getInt("UFrom") + " " + rs2.getString("Content") + " " + rs2.getTimestamp("CTime").getTime() + " ").getBytes("UTF-8"), used2);
                        }while (rs2.next() && tmp2 != used2);
                        used2 = Utils.addbyte(bytetmp2, ("" + (tmp2 != used2 ? 0 : -1)).getBytes("UTF-8"), tmp2);
                        bt = new byte[used2];
                        System.arraycopy(bytetmp2, 0, bt, 0, used2);
                        break;
                    case 18://注销
                        ServerMain.database.logout(psend[1], Integer.parseInt(psend[2]));
                        bt = "19 OK".getBytes("UTF-8");
                        break;

                }
            }


            packet.setData(bt);
            UDPServer.response(packet);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}